﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Shell;
using System.ComponentModel.Design;

namespace MicroLink.StsDev2008AddIn.CommandHandlers
{
    public abstract class MenuCommandHandler
    {
        private readonly Package m_package;
        private readonly CommandID m_commandId;
        private OleMenuCommand m_menuCommand;

        private bool m_isBound;

        protected internal MenuCommandHandler(Package package)
        {
            m_package = package;
            foreach (object attr in GetType().GetCustomAttributes(false))
            {
                CommandIDAttribute idAttr = attr as CommandIDAttribute;
                if (idAttr != null)
                {
                    m_commandId = new CommandID(idAttr.Guid, (int)idAttr.Command);
                }
            }
        }

        public CommandID CommandId { get { return m_commandId; } }
        protected Package Package { get { return m_package; } }
        protected IServiceProvider ServiceProvider { get { return m_package; } }
        protected OleMenuCommand MenuCommand { get { return m_menuCommand; } }
        public bool IsBound { get { return m_isBound; } }


        protected virtual void OnExecute(OleMenuCommand command) { ; }
        protected virtual void OnQueryStatus(OleMenuCommand command) { ; }
        protected virtual void OnChange(OleMenuCommand command) { ; }

        public void Bind()
        {
            if (m_package == null) return;

            OleMenuCommandService mcs = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

            if (mcs == null) return;

            m_menuCommand = new OleMenuCommand(
              ExecuteMenuCommandCallback,
              ChangeCallback,
              BeforeStatusQueryCallback,
              m_commandId);
            mcs.AddCommand(m_menuCommand);

            m_isBound = true;
        }

        private void ExecuteMenuCommandCallback(object sender, EventArgs e)
        {
            OleMenuCommand command = sender as OleMenuCommand;
            if (command != null) OnExecute(command);
        }

        private void ChangeCallback(object sender, EventArgs e)
        {
            OleMenuCommand command = sender as OleMenuCommand;
            if (command != null) OnChange(command);
        }

        private void BeforeStatusQueryCallback(object sender, EventArgs e)
        {
            OleMenuCommand command = sender as OleMenuCommand;
            if (command != null) OnQueryStatus(command);
        }
    }
}
